import { app, BrowserWindow, ipcMain, Menu } from 'electron'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
import fs from 'node:fs'
import { v4 as uuidv4 } from 'uuid'
import matter from 'gray-matter'

// 格式化时间为YYYY-MM-DD HH:mm:ss格式
function formatDateTime() {
  const now = new Date()
  const year = now.getFullYear()
  const month = String(now.getMonth() + 1).padStart(2, '0')
  const day = String(now.getDate()).padStart(2, '0')
  const hours = String(now.getHours()).padStart(2, '0')
  const minutes = String(now.getMinutes()).padStart(2, '0')
  const seconds = String(now.getSeconds()).padStart(2, '0')
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

const __dirname = path.dirname(fileURLToPath(import.meta.url))

// 设置应用根目录
process.env.APP_ROOT = path.join(__dirname, '../..')

export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron')
export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist')
export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL

process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL
  ? path.join(process.env.APP_ROOT, 'public')
  : RENDERER_DIST

// 定义默认笔记目录路径
const NOTES_DIR = path.join(app.getPath('appData'), 'MarkNote', 'notes')

// 确保应用程序单实例运行
if (!app.requestSingleInstanceLock()) {
  app.quit()
  process.exit(0)
}

let win = null
const preload = path.join(__dirname, '../preload/index.mjs')
const indexHtml = path.join(RENDERER_DIST, 'index.html')

// 初始化应用数据目录
function initializeAppData() {
  // 创建笔记目录
  if (!fs.existsSync(NOTES_DIR)) {
    fs.mkdirSync(NOTES_DIR, { recursive: true })
    console.log(`笔记目录已创建: ${NOTES_DIR}`)
  }
}

// 创建主窗口
async function createWindow() {
  win = new BrowserWindow({
    title: 'MarkNote',
    width: 1200,
    height: 800,
    minWidth: 800,
    minHeight: 600,
    webPreferences: {
      preload
    },
    autoHideMenuBar: true
  })

  // 默认全屏显示
  win.maximize()

  if (VITE_DEV_SERVER_URL) {
    // 开发模式下加载开发服务器
    win.loadURL(VITE_DEV_SERVER_URL)
    win.webContents.openDevTools()
  } else {
    // 生产模式下加载打包后的HTML
    win.loadFile(indexHtml)
  }
}

// 应用事件处理
app.whenReady().then(() => {
  // 设置空菜单以完全隐藏菜单栏
  Menu.setApplicationMenu(null);
  initializeAppData()
  createWindow()
})

// 处理窗口关闭事件
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

// 设置子页
ipcMain.handle('set-note-as-child', (_, { childPath, parentPath }) => {
  try {
    const childContent = fs.readFileSync(childPath, 'utf8')
    const { data, content } = matter(childContent)

    data.parent = parentPath
    data.updated = formatDateTime()

    const newContent = matter.stringify(content, data)
    fs.writeFileSync(childPath, newContent, 'utf8')
    return true
  } catch (error) {
    console.error('设置子页失败:', error)
    throw error
  }
})

// 升级顶级笔记
ipcMain.handle('promote-note-to-top', (_, notePath) => {
  try {
    const content = fs.readFileSync(notePath, 'utf8')
    const { data, content: body } = matter(content)

    delete data.parent
    data.updated = formatDateTime()

    const newContent = matter.stringify(body, data)
    fs.writeFileSync(notePath, newContent, 'utf8')
    return true
  } catch (error) {
    console.error('升级顶级失败:', error)
    throw error
  }
})

// 获取笔记列表
ipcMain.handle('get-notes-list', () => {
  try {
    const files = fs.readdirSync(NOTES_DIR)
    const notes = files.filter(file => file.endsWith('.md')).map(file => {
      const filePath = path.join(NOTES_DIR, file)
      const fileContent = fs.readFileSync(filePath, 'utf8')

      try {
        // 解析Front Matter
        const { data } = matter(fileContent)
        return {
          name: data.title || '未命名笔记',
          path: filePath,
          updated: data.updated || null,
          sort: data.sort || 0,
          isGroup: !!data.isGroup,
          parent: data.parent || null
        }
      } catch (error) {
        console.warn(`解析笔记失败: ${file}`, error)
        return {
          name: file.replace('.md', ''),
          path: filePath,
          updated: null,
          sort: 0,
          isGroup: false,
          parent: null
        }
      }
    })

    // 按路径排序（确保 parent 在 child 前）
    notes.sort((a, b) => a.path.localeCompare(b.path))
    return notes
  } catch (error) {
    console.error('获取笔记列表失败:', error)
    return []
  }
})

// 读取笔记内容
ipcMain.handle('read-note', (_, notePath) => {
  try {
    const fileContent = fs.readFileSync(notePath, 'utf8')
    // 解析Front Matter并只返回内容部分
    const { content } = matter(fileContent)
    return content.trim()
  } catch (error) {
    console.error('读取笔记失败:', error)
    throw error
  }
})

// 保存笔记
ipcMain.handle('save-note', (_, { path: notePath, content }) => {
  try {
    let metadata = {}
    const now = formatDateTime()

    // 检查文件是否已存在
    if (fs.existsSync(notePath)) {
      // 如果存在，读取现有Front Matter
      const existingContent = fs.readFileSync(notePath, 'utf8')
      const { data } = matter(existingContent)
      metadata = data
      // 更新updated时间
      metadata.updated = now
    } else {
      // 获取最大 sort
      let maxSort = 0
      try {
        const files = fs.readdirSync(NOTES_DIR)
        const notes = files
          .filter(file => file.endsWith('.md'))
          .map(file => {
            const c = fs.readFileSync(path.join(NOTES_DIR, file), 'utf8')
            const { data } = matter(c)
            return data.sort || 0
          })
        maxSort = notes.length > 0 ? Math.max(...notes) : 0
      } catch (e) { }

      metadata = {
        id: uuidv4(),
        title: '未命名笔记',
        created: now,
        updated: now,
        sort: maxSort + 1
      }
    }

    // 组合新的文件内容
    const newContent = matter.stringify(content, metadata)
    fs.writeFileSync(notePath, newContent, 'utf8')

    return {
      success: true,
      title: metadata.title
    }
  } catch (error) {
    console.error('保存笔记失败:', error)
    throw error
  }
})

// 新建笔记
ipcMain.handle('create-note', () => {
  try {
    const id = uuidv4()
    const now = formatDateTime()
    const fileName = `${id}.md`
    const filePath = path.join(NOTES_DIR, fileName)

    // 获取当前最大 sort 值
    let maxSort = 0
    try {
      const files = fs.readdirSync(NOTES_DIR)
      const notes = files
        .filter(file => file.endsWith('.md'))
        .map(file => {
          const content = fs.readFileSync(path.join(NOTES_DIR, file), 'utf8')
          const { data } = matter(content)
          return data.sort || 0
        })
      maxSort = notes.length > 0 ? Math.max(...notes) : 0
    } catch (e) {
      console.warn('读取现有笔记排序失败，使用默认 sort=0')
    }

    // 创建包含Front Matter的笔记内容
    const metadata = {
      id: id,
      title: '未命名笔记',
      created: now,
      updated: now,
      sort: maxSort + 1
    }

    const content = matter.stringify('', metadata)
    fs.writeFileSync(filePath, content, 'utf8')

    return {
      name: metadata.title,
      path: filePath,
      id: id
    }
  } catch (error) {
    console.error('创建笔记失败:', error)
    throw error
  }
})

// 删除笔记
ipcMain.handle('delete-note', (_, notePath) => {
  try {
    if (fs.existsSync(notePath)) {
      fs.unlinkSync(notePath)
      return true
    }
    return false
  } catch (error) {
    console.error('删除笔记失败:', error)
    throw error
  }
})

// 更新笔记标题
ipcMain.handle('update-note-title', (_, { path: notePath, title }) => {
  try {
    const fileContent = fs.readFileSync(notePath, 'utf8')
    const { data, content } = matter(fileContent)

    // 更新标题和修改时间
    data.title = title
    data.updated = formatDateTime()

    // 重新组合内容并保存
    const newContent = matter.stringify(content, data)
    fs.writeFileSync(notePath, newContent, 'utf8')

    return true
  } catch (error) {
    console.error('更新笔记标题失败:', error)
    throw error
  }
})

// 更新笔记排序
ipcMain.handle('update-note-sort', async (_, noteSorts) => {
  try {
    for (const { path: notePath, sort } of noteSorts) {
      const fileContent = fs.readFileSync(notePath, 'utf8')
      const { data, content } = matter(fileContent)

      // 更新排序字段
      data.sort = sort

      // 重新组合内容并保存
      const newContent = matter.stringify(content, data)
      fs.writeFileSync(notePath, newContent, 'utf8')
    }
    return true
  } catch (error) {
    console.error('更新笔记排序失败:', error)
    throw error
  }
})